// SplashWnd.cpp : implementation file
/*********************************************************************
*	Author         : orbit
*	Date           : April 16, 1998
* Last-modified  : October 11, 2001 
*	Contact us     : inte2000@163.com,support@winmsg.com
*	Web Page       : http://www.winmsg.com/cn/orbit.htm (for Chinese version)
*						       http://www.winmsg.com/orbit.htm (for English version)
**********************************************************************/
#include "stdafx.h"
#include "SplashWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define DELAY    1000    // minimum delay in millis

/////////////////////////////////////////////////////////////////////////////
// CSplashWnd

CSplashWnd::CSplashWnd(UINT nBitmapID)
{
	m_nBitmapID = nBitmapID;
	m_TimerID = 0;
}

CSplashWnd::~CSplashWnd()
{
}

BEGIN_MESSAGE_MAP(CSplashWnd, CWnd)
	//{{AFX_MSG_MAP(CSplashWnd)
	ON_WM_PAINT()
	ON_WM_TIMER()
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()



BOOL CSplashWnd::Create()
{
	if( !GetBitmapAndPalette(m_nBitmapID, m_bitmap, m_pal) )
	{
		TRACE1( "Could not load bitmap resource - %d\n", m_nBitmapID );
		return FALSE;
	}

	BITMAP bm;
	m_bitmap.GetObject(sizeof(BITMAP), &bm);
	//WS_EX_TOPMOST
	// Create the the splash window with invisible parent as parent
	BOOL bRetVal = CWnd::CreateEx(WS_EX_TOPMOST|WS_EX_TOOLWINDOW, 
			AfxRegisterWndClass(CS_CLASSDC), 
			_T(""), WS_POPUP, 0, 0, 
			bm.bmWidth, bm.bmHeight, GetDesktopWindow()->m_hWnd, NULL);

	CenterWindow();
	ShowWindow(SW_SHOW);
	UpdateWindow();
	
	return bRetVal;
}

void CSplashWnd::PostNcDestroy() 
{
   delete this;
}


BOOL CSplashWnd::GetBitmapAndPalette(UINT nIDResource, CBitmap &bitmap, CPalette &pal)
{
	LPCTSTR lpszResourceName = (LPCTSTR)nIDResource;

	HBITMAP hBmp = (HBITMAP)::LoadImage( AfxGetInstanceHandle(), 
			lpszResourceName, IMAGE_BITMAP, 0,0, LR_CREATEDIBSECTION );

	if( hBmp == NULL ) 
		return FALSE;

	bitmap.Attach( hBmp );

	// Create a logical palette for the bitmap
	DIBSECTION ds;
	BITMAPINFOHEADER &bmInfo = ds.dsBmih;
	bitmap.GetObject( sizeof(ds), &ds );

	int nColors = bmInfo.biClrUsed ? bmInfo.biClrUsed : 1 << bmInfo.biBitCount;

	// Create a halftone palette if colors > 256. 
	CClientDC dc(NULL);			// Desktop DC
	if( nColors > 256 )
		pal.CreateHalftonePalette( &dc );
	else
	{
		// Create the palette

		RGBQUAD *pRGB = new RGBQUAD[nColors];
		CDC memDC;

		ZeroMemory(pRGB, sizeof(RGBQUAD) * nColors);

		memDC.CreateCompatibleDC(&dc);
		CBitmap *ob = memDC.SelectObject( &bitmap );
		::GetDIBColorTable( memDC, 0, nColors, pRGB );

		UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * nColors);
		LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];

		pLP->palVersion = 0x300;
		pLP->palNumEntries = nColors;

		for( int i=0; i < nColors; i++)
		{
			pLP->palPalEntry[i].peRed = pRGB[i].rgbRed;
			pLP->palPalEntry[i].peGreen = pRGB[i].rgbGreen;
			pLP->palPalEntry[i].peBlue = pRGB[i].rgbBlue;
			pLP->palPalEntry[i].peFlags = 0;
		}

		pal.CreatePalette( pLP );
		memDC.SelectObject(ob);
		memDC.DeleteDC();
		delete[] pLP;
		delete[] pRGB;
	}

	return TRUE;
}

void CSplashWnd::OnPaint() 
{
  CPaintDC dc(this); // device context for painting
	
	CDC memDC;
	memDC.CreateCompatibleDC( &dc );

	CBitmap *pBmpOld = memDC.SelectObject( &m_bitmap );
	CPalette *op;
	// Select and realize the palette
	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL )
	{
		op = dc.SelectPalette( &m_pal, FALSE );
		dc.RealizePalette();
	}

	// Window is same size as bitmap
	CRect rcWnd;
	GetWindowRect( &rcWnd );
	dc.BitBlt(0, 0, rcWnd.Width(), rcWnd.Height(), &memDC, 0, 0,SRCCOPY);

	if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE && m_pal.m_hObject != NULL )
	{
		dc.SelectPalette( op, FALSE );
	}

	// Restore bitmap in memDC
	memDC.SelectObject( pBmpOld );
	memDC.DeleteDC();
	// Do not call CWnd::OnPaint() for painting messages
}


void CSplashWnd::OnTimer(UINT nIDEvent) 
{
	KillTimer(0x108);
	m_TimerID = 0;
	DestroyWindow();
//	CWnd::OnTimer(nIDEvent);
}

int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	m_TimerID = SetTimer(0x108,DELAY,NULL);
//	SetCapture();
	return 0;
}

BOOL CSplashWnd::PreTranslateMessage(MSG* pMsg) 
{
	if (pMsg->message == WM_KEYDOWN ||
	    pMsg->message == WM_SYSKEYDOWN ||
	    pMsg->message == WM_LBUTTONDOWN ||
	    pMsg->message == WM_RBUTTONDOWN ||
	    pMsg->message == WM_MBUTTONDOWN ||
	    pMsg->message == WM_NCLBUTTONDOWN ||
	    pMsg->message == WM_NCRBUTTONDOWN ||
	    pMsg->message == WM_NCMBUTTONDOWN)
	{
		DestroyWindow();
		return TRUE;	// message handled here
	}

	return FALSE;	// message not handled
}

BOOL CSplashWnd::DestroyWindow() 
{
//	ReleaseCapture();
	m_bitmap.DeleteObject();
	m_pal.DeleteObject();
	if(m_TimerID != 0)
		KillTimer(m_TimerID);
	return CWnd::DestroyWindow();
}
